package com.cci.kangdao.azureAD;

import com.cci.kangdao.common.RedisKeys;
import com.cci.kangdao.redis.RedisClientUtils;
import com.cci.kangdao.service.PropertiesUtils;
import com.cci.kangdao.utilTool.HttpUtils;
import com.cci.kangdao.utilTool.JsonUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author William Du
 * @date 2019/5/17
 */
@Service
public class AzureService {

    private static Logger log = Logger.getLogger(AzureService.class);

    @Resource
    private PropertiesUtils propertiesUtils;
    @Resource
    private RedisClientUtils redisClientUtils;

    public String getManagementToken() {
        String webClientId = propertiesUtils.getPropertiesValue("webClient_id");
        // 先查询缓存中是否存在token
        String managementTokenKey = RedisKeys.managementTokenKey(webClientId);
        if (redisClientUtils.exists(managementTokenKey)) {
            // 缓存存在，返回token
            return redisClientUtils.get(managementTokenKey);
        }
        // 通过远程获取token信息
        String webClientSecret = propertiesUtils.getPropertiesValue("webClientSecret");
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        StringBuffer sb = new StringBuffer("https://login.partner.microsoftonline.cn/").append(tenant).append("/oauth2/v2.0/token");
        List<NameValuePair> parameter = new ArrayList<>();
        parameter.add(new BasicNameValuePair("grant_type", "client_credentials"));
        parameter.add(new BasicNameValuePair("client_id", webClientId));
        parameter.add(new BasicNameValuePair("client_secret", webClientSecret));
        parameter.add(new BasicNameValuePair("Scope", "https://microsoftgraph.chinacloudapi.cn/.default"));
        String response = HttpUtils.postForm(sb.toString(), parameter, new ResponseHandler<String>() {
            @Override
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                if (response.getStatusLine().getStatusCode() == 200) {
                    HttpEntity httpEntity = response.getEntity();
                    return EntityUtils.toString(httpEntity);
                } else {
                    /**
                     * 注释log
                     * 20230808
                     * sxt 处理Privacy Violation
                     */
                    //log.error("AD获取token异常，response：" + response);
                }
                return null;
            }
        });
        //接口正常响应，解析响应数据
        if (StringUtils.isNotEmpty(response)) {
            ManagementToken token = JsonUtils.toJavaObject(response, ManagementToken.class);
            //将获取到的token放入缓存，缓存时间59*60秒
            redisClientUtils.set(managementTokenKey, token.getAccessToken(), 3540);
            return token.getAccessToken();
        }
        return null;
    }

    public String addUser(String username, String password, String token) {
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        String url = "https://microsoftgraph.chinacloudapi.cn/v1.0/users";
        Map<String, Object> passwordProfile = new HashMap<String, Object>();
        passwordProfile.put("password", password);
        passwordProfile.put("forceChangePasswordNextSignIn", false);
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("accountEnabled", true);
        data.put("displayName", username);
        data.put("mailNickname", username);
        data.put("passwordProfile", passwordProfile);
        data.put("userPrincipalName", username + "@" + tenant);
        Header auth = new BasicHeader("Authorization", "Bearer " + token);
        String response = HttpUtils.postJson(url, JsonUtils.toJsonString(data), new ResponseHandler<String>() {
            @Override
            public String handleResponse(HttpResponse response)
                    throws ClientProtocolException, IOException {
                if (response.getStatusLine().getStatusCode() == 201) {
                    HttpEntity httpEntity = response.getEntity();
                    return EntityUtils.toString(httpEntity);
                } else {
                    /**
                     * 注释log
                     * 20230808
                     * sxt 处理Privacy Violation
                     */
                    //log.error("增加用户发生异常，响应体：" + EntityUtils.toString(response.getEntity()));
                }
                return null;
            }
        }, auth);
        return response;
    }

    public String getUser(String username, String token) {
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        StringBuffer sb = new StringBuffer("https://microsoftgraph.chinacloudapi.cn/v1.0/users/").append(username).append("@").append(tenant);
        Header authorizationHeader = new BasicHeader("Authorization", "Bearer " + token);
        String response = HttpUtils.get(sb.toString(), new ResponseHandler<String>() {
            @Override
            public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                if (response.getStatusLine().getStatusCode() == 200) {
                    HttpEntity httpEntity = response.getEntity();
                    return EntityUtils.toString(httpEntity);
                }
                log.error("AD获取用户异常，response：" + response);
                return null;
            }
        }, authorizationHeader);
        return response;
    }

    public Boolean lockUser(String username, String token) {
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        Map<String, Object> userProfile = new HashMap<>();
        userProfile.put("accountEnabled", false);
        return updateUserProfile(username, token, userProfile);
    }

    public boolean modifyUserPassword(String username, String token, String password) {
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        Map<String, Object> userProfile = new HashMap<>();
        Map<String, Object> passwordProfile = new HashMap<>();
        passwordProfile.put("password", password);
        passwordProfile.put("forceChangePasswordNextSignIn", false);
        userProfile.put("passwordProfile", passwordProfile);
        return updateUserProfile(username, token, userProfile);
    }

    private boolean updateUserProfile(String username, String token, Map<String, Object> profile) {
        String tenant = propertiesUtils.getPropertiesValue("tenant");
        StringBuffer sb = new StringBuffer("https://microsoftgraph.chinacloudapi.cn/v1.0/users/").append(username).append("@").append(tenant);
        Header authorizationHeader = new BasicHeader("Authorization", "Bearer " + token);
        Boolean flag = HttpUtils.patchJson(sb.toString(), JsonUtils.toJsonString(profile), new ResponseHandler<Boolean>() {
            @Override
            public Boolean handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
                if (response.getStatusLine().getStatusCode() == 204) {
                    return true;
                } else {
                    log.error("AD修改用户异常，response：" + response);
                    return false;
                }
            }
        }, authorizationHeader);
        return flag;
    }

}
